#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE CompressionTest
#include "../Common/Compression/Compress.h"
#include "boost/test/unit_test.hpp"
#include "boost/random.hpp"

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <Shellapi.h>

#include <iostream>
#include <fstream>
using namespace std;

boost::random::mt19937 Generator(static_cast<uint32_t>(std::time(0)));

string NewTemporyDirectory()
{
    boost::random::uniform_int_distribution<> Range(1, 65535);

    char Buffer[MAX_PATH + 1] = {0};
    GetTempPath(MAX_PATH, Buffer);

    char FileName[MAX_PATH + 1] = {0};
    GetTempFileName(Buffer, "XXX", Range(Generator), FileName);

    string Result = FileName;

    return Result;
}

struct DirectoryFixture
{
    string Directory;
    DirectoryFixture();
    ~DirectoryFixture();
};

DirectoryFixture::DirectoryFixture()
{
    Directory = NewTemporyDirectory();
    CreateDirectory(Directory.c_str(), 0);
}

DirectoryFixture::~DirectoryFixture()
{
    SHFILEOPSTRUCT Operation;
    Operation.hwnd = 0;
    Operation.wFunc = FO_DELETE;
    Operation.pFrom = Directory.c_str();
    Operation.pTo = 0;
    Operation.fFlags = FOF_SILENT | FOF_NOCONFIRMATION;
    SHFileOperation(&Operation);
}

BOOST_AUTO_TEST_CASE(Encode_Decode)
{
    DirectoryFixture X;
    string Data = "Some data expected to be compressed";
    ofstream Output;
    Output.open(X.Directory + "\\test.txt");
    Output << Data;
    Output.close();

    int Check = EncodeFile((X.Directory + "\\test.txt").c_str(), (X.Directory + "\\test.txt.compressed").c_str());
    BOOST_CHECK(Check == 0);

    DeleteFile((X.Directory + "\\test.txt").c_str());

    Check = DecodeFile((X.Directory + "\\test.txt.compressed").c_str(), (X.Directory + "\\test.txt.uncompressed").c_str());
    BOOST_CHECK(Check == 0);

    ifstream Input;
    Input.open(X.Directory + "\\test.txt.uncompressed");
    char Buffer[512] = {0};
    Input.getline(Buffer, 512);
    Input.close();

    BOOST_CHECK(Data == Buffer);
}
